﻿import { Component, Injector } from '@angular/core';
import { PermissionTreeEditModel } from '@app/admin/shared/permission-tree-edit.model';
import { AppComponentBase } from '@shared/common/app-component-base';
import { ArrayToTreeConverterService } from '@shared/utils/array-to-tree-converter.service';
import { TreeDataHelperService } from '@shared/utils/tree-data-helper.service';
import { FlatPermissionDto } from '@shared/service-proxies/stock-service-proxies';
import { TreeNode } from 'primeng/api';
import * as _ from 'lodash';

@Component({
    selector: 'permission-tree',
    template: `
        <div class="form-group">
            <input
                type="text"
                (input)="filterPermissions($event)"
                [(ngModel)]="filter"
                class="form-control"
                placeholder="{{ 'SearchWithThreeDot' | localize }}"
            />
        </div>
        <p-tree
            [value]="treeData"
            [(selection)]="selectedPermissions"
            selectionMode="checkbox"
            (onNodeSelect)="nodeSelect($event)"
            (onNodeUnselect)="nodeUnSelect($event)"
            [propagateSelectionUp]="false"
        ></p-tree>
    `
})
export class PermissionTreeComponent extends AppComponentBase {
    set editData(val: PermissionTreeEditModel) {
        this.setTreeData(val.permissions);
        this.setSelectedNodes(val.grantedPermissionNames);
    }

    treeData: any;
    selectedPermissions: TreeNode[] = [];
    filter = '';

    constructor(
        private _arrayToTreeConverterService: ArrayToTreeConverterService,
        private _treeDataHelperService: TreeDataHelperService,
        injector: Injector
    ) {
        super(injector);
    }

    setTreeData(permissions: FlatPermissionDto[]) {
        this.selectedPermissions = [];
        this.treeData = this._arrayToTreeConverterService.createTree(
            permissions,
            'parentName',
            'name',
            null,
            'children',
            [
                {
                    target: 'label',
                    source: 'displayName'
                },
                {
                    target: 'expandedIcon',
                    value: 'fa fa-folder-open m--font-warning'
                },
                {
                    target: 'collapsedIcon',
                    value: 'fa fa-folder m--font-warning'
                },
                {
                    target: 'expanded',
                    targetFunction(item) {
                        return item.isExpandedDefault;
                    }
                }
            ]
        );
    }

    setSelectedNodes(grantedPermissionNames: string[]) {
        _.forEach(grantedPermissionNames, permission => {
            let item = this._treeDataHelperService.findNode(this.treeData, { data: { name: permission } });
            if (item) {
                this.selectedPermissions.push(item);
            }
        });
    }

    getGrantedPermissionNames(): string[] {
        if (!this.selectedPermissions || !this.selectedPermissions.length) {
            return [];
        }

        let permissionNames = [];

        for (let i = 0; i < this.selectedPermissions.length; i++) {
            permissionNames.push(this.selectedPermissions[i].data.name);
        }

        return permissionNames;
    }

    nodeSelect(event) {        
        let parentNode = this._treeDataHelperService.findParent(this.treeData, {
            data: { name: event.node.data.name }
        });

        while (parentNode != null) {          
            this.selectedPermissions.push(parentNode);
            parentNode = this._treeDataHelperService.findParent(this.treeData, {
                data: { name: parentNode.data.name }
            });
        }

        if(!event.parent){
            this.getCurrentNodeAndChildenNode(event, true);
        }
    }
    
    //获取选中节点及其所有子节点名称和权限名称并设置是否选中
    getCurrentNodeAndChildenNode(event,ischecked){
        this.currentSelectedNodeNames = new Array();
        this.currentSelectedPermissions= new Array();
        this.currentSelectedNodeNames.push(event.node.data.name);
        this.currentSelectedPermissions.push(event.node.data.name.split('_')[0]);
        if(event.node.children.length> 0){
            this.getNodeAndChildenNode(event.node);
        }
        this.setPermissionNode(this.treeData[0].children, ischecked);
    }

    currentSelectedNodeNames:any;
    currentSelectedPermissions:any;    
    getNodeAndChildenNode(node:TreeNode){         
        node.children.forEach(chiledNode=>{
            this.currentSelectedNodeNames.push(chiledNode.data.name);
            this.currentSelectedPermissions.push(chiledNode.data.name.split('_')[0]);
            if(chiledNode.children.length> 0){                
                this.getNodeAndChildenNode(chiledNode);
            }
        });
    }
    //遍历整个树，选中或取消与当前节点及其所有子节点的相同的权限的节点
    setPermissionNode(nodes:TreeNode[],  isChecked:boolean){ 
        nodes.forEach(element => {
            let nodeName = element.data.name;
            let permissionName = element.data.name.split('_')[0];
            
            if(this.currentSelectedNodeNames.indexOf(nodeName) < 0 &&
            this.currentSelectedPermissions.indexOf(permissionName) >= 0){
                if(isChecked== true){
                    if(this.selectedPermissions.indexOf(element) < 0){
                        this.selectedPermissions.push(element);
                        //选中父节点
                        this.selectParent(element);
                    }
                }else{
                    this.selectedPermissions = this.selectedPermissions.filter(p=>p!==element);
                }
            }

            if(element.children.length>0){
                this.setPermissionNode(element.children,isChecked);
            }
        });
    }

    selectParent(event){
        if(event.parent){
            if(this.selectedPermissions.indexOf(event.parent) < 0){
                this.selectedPermissions.push(event.parent);  
            }
            this.selectParent(event.parent); 
        }
    }

    nodeUnSelect(event){        
        if(!event.parent){
            this.getCurrentNodeAndChildenNode(event, false);
        }
    }

    filterPermissions(event): void {
        this.filterPermission(this.treeData, this.filter);
    }

    filterPermission(nodes, filterText): any {
        _.forEach(nodes, node => {
            if (node.data.displayName.toLowerCase().indexOf(filterText.toLowerCase()) >= 0) {
                node.styleClass = this.showParentNodes(node);
            } else {
                node.styleClass = 'hidden-tree-node';
            }

            if (node.children) {
                this.filterPermission(node.children, filterText);
            }
        });
    }

    showParentNodes(node): void {
        if (!node.parent) {
            return;
        }

        node.parent.styleClass = '';
        this.showParentNodes(node.parent);
    }
}
